﻿#include "Matrix.h"
#include <cstdlib>
#include <ctime>
#include <stdexcept>
using namespace std;

// 构造函数实现
Matrix::Matrix(int rows, int cols) : rows(rows), cols(cols) {
    // 检查行列有效性
    if (rows < 0 || cols < 0) {
        throw invalid_argument("行列大小必须为非负数");
    }
    // 处理0x0矩阵
    if (rows == 0 || cols == 0) {
        this->rows = this->cols = 0;
        data = nullptr;
        return;
    }
    allocate_memory();  // 分配内存
}

// 拷贝构造函数
Matrix::Matrix(const Matrix& other) : rows(other.rows), cols(other.cols) {
    allocate_memory();  // 分配内存
    // 深拷贝数据
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            data[i][j] = other.data[i][j];
}

// 析构函数
Matrix::~Matrix() {
    // 释放动态分配的内存
    if (data) {
        for (int i = 0; i < rows; ++i)
            delete[] data[i];
        delete[] data;
        data = nullptr; // 避免悬空指针
    }
}

// 内存分配函数
void Matrix::allocate_memory() {
    // 分配行指针数组
    data = new double* [rows];
    for (int i = 0; i < rows; ++i) {
        // 为每行分配空间
        data[i] = new double[cols];
        // 初始化为0
        for (int j = 0; j < cols; ++j)
            data[i][j] = 0.0;
    }
}

// 赋值运算符重载
Matrix& Matrix::operator=(const Matrix& other) {
    // 防止自赋值
    if (this != &other) {
        // 释放原有内存
        if (data) {
            for (int i = 0; i < rows; ++i)
                delete[] data[i];
            delete[] data;
            data = nullptr; // 避免悬空指针
        }

        // 复制维度信息
        rows = other.rows;
        cols = other.cols;
        // 重新分配内存
        allocate_memory();

        // 复制数据
        for (int i = 0; i < rows; ++i)
            for (int j = 0; j < cols; ++j)
                data[i][j] = other.data[i][j];
    }
    return *this;
}

// 矩阵加法实现
Matrix Matrix::operator+(const Matrix& other) {
    // 检查是否为空矩阵
    if (rows == 0 || cols == 0 || other.rows == 0 || other.cols == 0)
        throw invalid_argument("空矩阵无法进行加法操作");

    // 检查维度匹配
    if (rows != other.rows || cols != other.cols)
        throw invalid_argument("矩阵维度不匹配，无法相加");

    Matrix result(rows, cols);
    // 逐元素相加
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            result.data[i][j] = data[i][j] + other.data[i][j];
    return result;
}

// 矩阵减法实现
Matrix Matrix::operator-(const Matrix& other) {
    // 检查维度匹配
    if (rows != other.rows || cols != other.cols)
        throw invalid_argument("矩阵维度不匹配，无法相减");

    Matrix result(rows, cols);
    // 逐元素相减
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            result.data[i][j] = data[i][j] - other.data[i][j];
    return result;
}

// 矩阵乘法实现
Matrix Matrix::operator*(const Matrix& other) const {
    // 检查维度匹配（前矩阵列数=后矩阵行数）
    if (cols != other.rows)
        throw invalid_argument("矩阵维度不匹配，无法相乘");

    Matrix result(rows, other.cols);
    // 三重循环实现矩阵乘法
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < other.cols; ++j)
            for (int k = 0; k < cols; ++k)
                result.data[i][j] += data[i][k] * other.data[k][j];
    return result;
}

// 标量乘法（右乘）
Matrix Matrix::operator*(double scalar) const {
    Matrix result(rows, cols);
    // 逐元素乘以标量
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            result.data[i][j] = data[i][j] * scalar;
    return result;
}

// 标量乘法（左乘，友元函数）
Matrix operator*(double scalar, const Matrix& matrix) {
    // 复用右乘实现
    return matrix * scalar;
}

// 下标访问运算符（非常量版本）
double* Matrix::operator[](int row) {
    if (row < 0 || row >= rows) {
        throw out_of_range("Row index out of range");
    }
    return data[row];
}

// 下标访问运算符（常量版本）
const double* Matrix::operator[](int row) const {
    if (row < 0 || row >= rows) {
        throw out_of_range("Row index out of range");
    }
    return data[row];
}

// 输出流运算符
ostream& operator<<(ostream& os, const Matrix& matrix) {
    // 逐行逐列输出矩阵
    for (int i = 0; i < matrix.rows; ++i) {
        for (int j = 0; j < matrix.cols; ++j)
            os << matrix.data[i][j] << "\t";  // 制表符分隔元素
        os << "\n";  // 换行
    }
    return os;
}

// 输入流运算符
istream& operator>>(istream& is, Matrix& matrix) {
    // 逐行逐列读取矩阵
    for (int i = 0; i < matrix.rows; ++i)
        for (int j = 0; j < matrix.cols; ++j)
            is >> matrix.data[i][j];
    return is;
}

// 随机初始化函数
void Matrix::initRandomly(double min, double max) {
    static bool seed_initialized = false;
    if (!seed_initialized) {
        srand(time(nullptr)); // 仅初始化一次种子
        seed_initialized = true;
    }
    // 生成[min, max]范围内的随机数
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            data[i][j] = min + (max - min) * (rand() / (double)RAND_MAX);
}

bool Matrix::invert() {
    if (rows != cols) return false; // 只支持方阵
    int n = rows;
    Matrix temp(*this); // 拷贝原矩阵
    Matrix inv(n, n);
    // 初始化为单位阵
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            inv.data[i][j] = (i == j) ? 1.0 : 0.0;
    
    for (int i = 0; i < n; ++i) {
        // 寻找主元
        double maxA = fabs(temp.data[i][i]);
        int maxRow = i;
        for (int k = i + 1; k < n; ++k) {
            if (fabs(temp.data[k][i]) > maxA) {
                maxA = fabs(temp.data[k][i]);
                maxRow = k;
            }
        }
        if (maxA < 1e-12) return false; // 奇异矩阵

        // 行交换
        if (maxRow != i) {
            std::swap(temp.data[i], temp.data[maxRow]);
            std::swap(inv.data[i], inv.data[maxRow]);
        }

        // 归一化主元行
        double diag = temp.data[i][i];
        for (int j = 0; j < n; ++j) {
            temp.data[i][j] /= diag;
            inv.data[i][j] /= diag;
        }

        // 消元
        for (int k = 0; k < n; ++k) {
            if (k == i) continue;
            double factor = temp.data[k][i];
            for (int j = 0; j < n; ++j) {
                temp.data[k][j] -= factor * temp.data[i][j];
                inv.data[k][j] -= factor * inv.data[i][j];
            }
        }
    }
    // 结果赋值回自身
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            data[i][j] = inv.data[i][j];
    return true;
}

Matrix Matrix::transpose() const {
    Matrix result(cols, rows);
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            result.data[j][i] = data[i][j];
    return result;
}

void Matrix::test()
{
    Matrix m1(3, 3), m2(3, 3);
    // 手动初始化矩阵元素
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            m1[i][j] = i * 1 + j * 3;
            m2[i][j] = (i - 1) * 1 + (j + 1) * 0.5;
        }
    }
    // 输出两个矩阵
    cout << "矩阵1:\n" << m1 << "\n";
    cout << "矩阵2:\n" << m2 << "\n";
    // 矩阵加法
    Matrix sum = m1 + m2;
    cout << "矩阵和:\n" << sum << "\n";
    // 矩阵乘法
    Matrix product = m1 * m2;
    cout << "矩阵积:\n" << product << "\n";
    // 标量乘法
    Matrix scaled = 2.5 * m1;
    cout << "缩放矩阵:\n" << scaled << "\n";
    cout << endl;
}
